package br.com.rookgraph.branchreduce;

import br.com.rookgraph.Edge;
import br.com.rookgraph.Graph;
import br.com.rookgraph.heuristica.Plus2;

/**
 * Depuração do BrancheReduce conforme a
 * Heurística, especificada.
 *
 * @author Adalton Sena
 * @since 01-12-12
 * @changes 01-11-12
 *
 */
public class BranchReduceDepurationPlus extends BranchReducePlus  {

	private int interecaoExt;
	private int interecaoInt;

	public BranchReduceDepurationPlus(Graph original, Graph tree, Plus2 heuristica) {
		super(original, tree, heuristica);
	}

	@Override
	public Graph execute() {

		System.out.println("\n GRAFO ORIGINAL \n");
		getOriginal().showMatix();

		System.out.println("\n\n ARVORE INICIAL \n");
		getTree().showMatix();
		
		System.out.println("\n Depuracao: Não Estanque com Plus2 \n");

		Graph treefinal = super.execute();
		System.out.println("\n ARVORE FINAL \n");
		treefinal.showMatix();

		return treefinal;
	}

	@Override
	public Edge[] createCuttingList(){
		interecaoInt = 0;
		Edge[] listCut = super.createCuttingList();
		//System.out.println("\n");
		System.out.println("\n\n\t Iteração externa > "+ (++interecaoExt));
		System.out.println("\t\t Lista de corte: ");
		showEdges(listCut, false);
		return listCut;
	}

	@Override
	public Edge selectCutEdge(final Edge[] listCut) {
		Edge cutEdge = super.selectCutEdge(listCut);
		System.out.println("\n\t\t\t Iteração interna > "+ (++interecaoInt)+ "  (Escolhendo a Melhor Aresta de Corte)");
		System.out.print("\t\t\t\t Aresta de Corte: ");
		System.out.println(""+cutEdge);
		return cutEdge;
	}

	@Override
	public Edge[] createReplacementListToCuttingEdge(final Edge arestaCut){
		Edge[] repList = super.createReplacementListToCuttingEdge(arestaCut);
		System.out.println("\t\t\t\t Candidatas a Rep.:");
		showEdges(repList, true);
		return repList;
	}

	@Override
	public Edge selectEdgeFromReplamentList(final Edge[] listRep, Edge edgeCut) {
		int diffAlfa, diffGama = 100;
		Edge repEdge = super.selectEdgeFromReplamentList(listRep, edgeCut);
		if (repEdge  != null) {
			System.out.print("\tSimulando Troca ==> ");		
			System.out.print("\tReplace:");
			//ganhoTroca = (repEdge.alfa-edgeCut.alfa) +(repEdge.gama - edgeCut.gama);
			if (repEdge.gama == 2) { 
				repEdge.gama = getOriginal().order;
			}else if ( repEdge.gama == 1) { 
				repEdge.gama = getOriginal().order+1;
			}

			diffAlfa = repEdge.alfa - edgeCut.alfa;
			diffGama = repEdge.gama - edgeCut.gama;
			System.out.println("   "+repEdge);
			System.out.println("\t DiffAlfa = "+ diffAlfa+ "   DiffGama = "+diffGama);
			//+" DiffGama = "+repEdge.gama-edgeCut.gama);
			//System.out.println("\t\t\t\t Ganho: "+ganhoTroca);
		}else {
			System.out.print("\t\t\t\t Replace:  " + repEdge+ "\n");
		}
		return repEdge;
	}

	@Override
	public boolean isTreeBest(Graph graphBest) {
		boolean treeBest = super.isTreeBest(graphBest);
		// System.out.println("\t\t\t\tA Arvore atual possui menos braches que a melhor? " + treeBest);
		return treeBest;
	}

	public void showEdges(Edge[] result, boolean nivel2) {
		String ident = nivel2 ? "\t\t\t\t\t\t  " : "\t\t\t";
		for (Edge edge : result) {
			System.out.println(ident+edge);
		}
	}

}
